package com.tomecode.rvr.generator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;

import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNStatus;

import com.tomecode.rvr.generator.filter.IgnorFilter;
import com.tomecode.rvr.generator.formate.FileFormateWriter;

/**
 * 
 * Report generator about file
 * 
 * @author Frastia Tomas
 * 
 */
public final class ReportGenerator {

	private static final SVNClientManager clientManager = SVNClientManager.newInstance();

	private Config config;

	private IgnorFilter ignorFilter;

	private FileFormateWriter fileFormateWriter;

	/**
	 * Construktor
	 * 
	 * @param config
	 * @throws IOException
	 */
	public ReportGenerator(Config config) throws IOException {
		this.config = config;
		this.ignorFilter = new IgnorFilter(config.getIgnoredFiles(), config.getIgnoredDirs());
		this.fileFormateWriter = new FileFormateWriter(createReportFileStream(), config.getType(), config.getInReport());

	}

	/**
	 * generate report
	 * 
	 * @throws IOException
	 */
	public final void generate() throws IOException {
		reportWorkspace(config.getWorkingDir());
		fileFormateWriter.generate();
	}

	/**
	 * 
	 * parse all files in {@link Config#getWorkingDir()}
	 * 
	 * @param dir
	 * @throws IOException
	 */
	private final void reportWorkspace(File dir) throws IOException {
		for (File file : dir.listFiles(ignorFilter)) {
			if (file.isDirectory() && file.getName().equals(".svn")) {
				continue;
			}
			if (file.isDirectory()) {
				reportWorkspace(file);
			} else if (file.isFile()) {
				reportInfoAboutFile(file);
			}
		}
	}

	/**
	 * get svn info about current file if {@link Config#isOnlyLocale()} is <b>true</b> then info will synchronized with svn
	 * 
	 * @param file
	 * @throws IOException
	 */
	private final void reportInfoAboutFile(File file) throws IOException {

		try {
			SVNStatus status = clientManager.getStatusClient().doStatus(file, config.isOnlyLocale());
			fileFormateWriter.append(status.getKind(), status.getAuthor(), status.getContentsStatus(), status.getRevision(), status.getCommittedDate(), file.getPath());
		} catch (SVNException e) {
			fileFormateWriter.append(SVNNodeKind.UNKNOWN, null, null, null, null, file.getPath());
		}
	}

	/**
	 * create a {@link Config#getReportFile()} if not exist and create
	 * {@link BufferedWriter}
	 * 
	 * @return
	 * @throws IOException
	 */
	private final File createReportFileStream() throws IOException {
		File report = config.getReportFile();
		if (report.isDirectory() && !report.exists()) {
			report = new File(report.getPath() + File.separator + "report." + config.getType().toString().toLowerCase());
		} else {
			if (!report.getParentFile().exists()) {
				report.getParentFile().mkdir();
			}
		}

		if (report.isDirectory()) {
			report = new File(report.getPath() + File.separator + "report." + config.getType().toString().toLowerCase());
		}
		if (!report.exists()) {
			report.createNewFile();
		}
		return report;
	}
}
